package com.xixibaby.storage.oss;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.RandomUtil;
import com.xixibaby.storage.FileResponse;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.xixibaby.core.Assert;
import com.xixibaby.storage.FileRequest;
import com.xixibaby.storage.FileUploadService;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author : tomj
 * @since : 2019-02-28 10:02
 */
public class OSSFileUploadServiceImpl implements FileUploadService {

    private static final Log LOGGER = LogFactory.getLog(OSSFileUploadServiceImpl.class);


    @Autowired
    private AliyunProperty aliyunProperty;



    @Override
    public String getFullPath(String image) {
        if(Assert.notEmpty(image)){
            if(image.startsWith("http")){
                return image;
            }
            return aliyunProperty.getOss().getLineUrl() + "/" + image;
        }
        return image;
    }

    private void valid(FileRequest vo){

    }


    private FileResponse parseBase64(FileRequest request){
        Assert.succ(request.getBase64()).thenThrow("base64字符串不能为空！");
        Assert.succ(request.getType()).thenThrow("上传类型不能为空！");
        String base64 = request.getBase64();
        String[] split = base64.split(",");
        request.setBase64(split[1]);
        request.setSuffix(getType(split[0]));
        String typeName =  request.getType();
        if(Assert.empty(request.getType())){
            typeName = "default";
        }

        FileResponse fileResponse = new FileResponse();
        OssProperties oss = aliyunProperty.getOss();
        String target = oss.getRootUrl() + "/" + typeName;
        StringBuilder builder = new StringBuilder();
        builder.append(RandomUtil.randomString(12)).append(".").append(request.getSuffix());
        String name = builder.toString();
        request.setName(name);
        //文件名
        //target  是路径
        String dbName = target + "/" + name;
        //数据库里面的名称
        fileResponse.setDbName(dbName);

        fileResponse.setPathName(oss.getLineUrl() + "/" + dbName);
        valid(request);
        return fileResponse;

    }

    private FileResponse parseFile(FileRequest request) throws IOException{
        MultipartFile file = request.getFile();
        Assert.succ(file).thenThrow("上传文件不能为空！");
        String typeName =  request.getType();
        if(Assert.empty(request.getType())){
            typeName = "file";
        }

        FileResponse fileResponse = new FileResponse();
        String fileName = file.getOriginalFilename();
        String extend = fileName.substring(fileName.lastIndexOf(".")+1);
        request.setSuffix(extend);

        String target = aliyunProperty.getOss().getRootUrl() + "/" + typeName;

        StringBuilder builder = new StringBuilder();
        builder.append(RandomUtil.randomString(12)).append(".").append(request.getSuffix());
        String name = builder.toString();
        //文件名
        request.setName(name);
        //target  是路径
        String dbName = target + "/" + name;
        //数据库里面的名称
        fileResponse.setDbName(dbName);
        fileResponse.setPathName(aliyunProperty.getOss().getLineUrl() + "/" + dbName);
        valid(request);
        return fileResponse;

    }


    @Override
    public FileResponse upload(FileRequest vo) {
        FileResponse fileResponse = parseBase64(vo);
        String objectName = fileResponse.getDbName();
        byte[] bytes = Base64.decode(vo.getBase64());
        OSS build = new OSSClientBuilder().build(aliyunProperty.getOss().getEndpoint(), aliyunProperty.getAppid(), aliyunProperty.getAppsecret());
        build.putObject(aliyunProperty.getOss().getBucketName(), objectName,new ByteArrayInputStream(bytes));
        build.shutdown();
        return fileResponse;
    }




    @Override
    public FileResponse uploadFile(FileRequest vo){
        InputStream in = null;
        String objectName = null;
        FileResponse fileResponse = null;

        try{
            fileResponse = parseFile(vo);
            objectName = fileResponse.getDbName();
            OSS build = new OSSClientBuilder().build(aliyunProperty.getOss().getEndpoint(), aliyunProperty.getAppid(), aliyunProperty.getAppsecret());
            byte[] bytes = vo.getFile().getBytes();
            build.putObject(aliyunProperty.getOss().getBucketName(), objectName,new ByteArrayInputStream(bytes));
            build.shutdown();
        }catch (IOException exception){
            LOGGER.error(exception.getMessage());
        }

        return fileResponse;
    }

    @Override
    public List<FileResponse> uploadBetchFile(FileRequest vo) {
        MultipartFile[] files = vo.getFiles();
        InputStream in = null;
        String objectName = null;
        List<FileResponse> fileResponses = new ArrayList<>();
        OSS build = new OSSClientBuilder().build(aliyunProperty.getOss().getEndpoint(), aliyunProperty.getAppid(), aliyunProperty.getAppsecret());
        for (int i = 0; i < files.length; i++) {
            vo.setFile(files[i]);

            try{
                FileResponse fileResponse = parseFile(vo);
                objectName = fileResponse.getDbName();
                byte[] bytes = vo.getFile().getBytes();
                build.putObject(aliyunProperty.getOss().getBucketName(), objectName,new ByteArrayInputStream(bytes));
                fileResponses.add(fileResponse);
            }catch (IOException exception){
                LOGGER.error(exception.getMessage());
            }
        }
        build.shutdown();

        return fileResponses;
    }

    private String getType(String str){
        String rgex = "data:image/(.*?);base64";
        Pattern pattern = Pattern.compile(rgex);
        Matcher m = pattern.matcher(str);
        while (m.find()){
            return m.group(1);
        }
        return "";
    }


}
